package model

import (
	"errors"
	"fmt"
	"github.com/spf13/cast"
	"go-vue/admin/conf"
	"log"
)

// SystemRoles 系统角色
type SystemRoles struct {
	RoleId    int64      `xorm:"autoincr role_id"`
	RolePid   int64      `xorm:"role_pid"`
	RoleLabel string     `xorm:"role_label"`
	RoleAlias string     `xorm:"role_alias"`
	RoleSort  int        `xorm:"role_sort"`
	State     conf.State `xorm:"state"`
}

func (role *SystemRoles) One() *SystemRoles {
	exist, err := conf.DbEngine.Get(role)
	if err != nil || exist == false {
		return nil
	}
	return role
}

// GetAllInitRoles 获取系统所有角色(角色管理编辑用)
func (role *SystemRoles) GetAllInitRoles() *InitOutput {
	var roleList []SystemRoles
	err := conf.DbEngine.Where("state = ?", conf.StateOn).OrderBy("role_sort asc").Cols("role_id,role_pid,role_label").Find(&roleList)
	if err != nil {
		return nil
	}
	result := &InitOutput{}
	var listInitSource = make(map[string]*InitOutputSource, 0)
	var listInitNodeTree []*InitOutputTreeNode
	if len(roleList) > 0 {
		for _, item := range roleList {
			value := cast.ToString(item.RoleId)
			tmp := &InitOutputSource{
				Label: item.RoleLabel,
				Pid:   cast.ToString(item.RolePid),
				Value: value,
			}
			listInitSource[value] = tmp
		}
		listInitNodeTree = role.BuildRolesChildInit(0, roleList)
	}
	result.Source = listInitSource
	result.TreeNode = listInitNodeTree
	return result
}

// BuildRolesChildInit 递归获取子角色(角色管理编辑用)
func (role *SystemRoles) BuildRolesChildInit(role_pid int64, roleList []SystemRoles) []*InitOutputTreeNode {
	var treeList []*InitOutputTreeNode
	for _, v := range roleList {
		if role_pid == v.RolePid {
			node := &InitOutputTreeNode{
				Label:    v.RoleLabel,
				Value:    cast.ToString(v.RoleId),
				Children: nil,
			}
			child := v.BuildRolesChildInit(v.RoleId, roleList)
			if len(child) != 0 {
				node.Children = child
			}
			treeList = append(treeList, node)
		}
	}
	return treeList
}

// SystemRolesEditList 角色列表(角色管理编辑用)
type SystemRolesEditList struct {
	Id       int64                  `json:"id"`
	ParentId int64                  `json:"parentId"`
	Label    string                 `json:"label"`
	Sort     int                    `json:"sort"`
	Alias    string                 `json:"alias"`
	State    conf.State             `json:"state"`
	Children []*SystemRolesEditList `json:"children,omitempty"`
}

// GetAllEditRoles 获取系统所有角色(角色管理编辑用)
func (role *SystemRoles) GetAllEditRoles() []*SystemRolesEditList {
	var roleList []SystemRoles
	err := conf.DbEngine.OrderBy("role_sort asc,role_pid").Find(&roleList)
	if err != nil {
		log.Println(err)
		return nil
	}

	var listEdit []*SystemRolesEditList
	if len(roleList) > 0 {
		listEdit = role.BuildMenuChildEdit(0, roleList)
	}
	return listEdit
}

// BuildMenuChildEdit 递归获取子角色(角色管理编辑用)
func (role *SystemRoles) BuildMenuChildEdit(pid int64, roleList []SystemRoles) []*SystemRolesEditList {
	var treeList []*SystemRolesEditList
	for _, v := range roleList {
		if pid == v.RolePid {
			node := &SystemRolesEditList{
				Id:       v.RoleId,
				ParentId: v.RolePid,
				Label:    v.RoleLabel,
				Sort:     v.RoleSort,
				Alias:    v.RoleAlias,
				State:    v.State,
				Children: nil,
			}
			child := v.BuildMenuChildEdit(v.RoleId, roleList)
			if len(child) != 0 {
				node.Children = child
			}
			treeList = append(treeList, node)
		}
	}
	return treeList
}

// SaveEditRole 编辑系统角色(角色管理编辑用)
func (role *SystemRoles) SaveEditRole(input *SystemRolesEditList) (id int64, err error) {
	//主表信息
	roleInfo := &SystemRoles{
		RoleId:    input.Id,
		RolePid:   input.ParentId,
		RoleLabel: input.Label,
		RoleAlias: input.Alias,
		RoleSort:  input.Sort,
		State:     input.State,
	}
	if input.Id != 0 {
		//更新主表
		_, err = conf.DbEngine.Where("role_id = ?", input.Id).Cols("role_pid,role_label,role_alias,role_sort,state").Update(roleInfo)
		if err != nil {
			return 0, err
		}
		id = input.Id
	} else { // 新增
		_, err = conf.DbEngine.Insert(roleInfo)
		if err != nil {
			return 0, err
		}
		id = roleInfo.RoleId
	}

	return id, err
}

// DelEditRole 删除列表
func (role *SystemRoles) DelEditRole(input *DeleteInputIds) error {
	delList := role.treeDel(input.Ids, input.Ids)
	fmt.Printf("delList === %+v\n", delList)
	if len(delList) == 0 {
		return errors.New("不存在删除的节点")
	}

	//删除主表
	_, err := conf.DbEngine.In("role_id", delList).Delete(role)
	if err != nil {
		return err
	}
	return nil
}

//递归删除
func (role *SystemRoles) treeDel(ids []int64, exist []int64) []int64 {
	list := make([]SystemRoles, 0)
	err := conf.DbEngine.In("role_pid", ids).Cols("role_id").Find(&list)
	if err != nil {
		return nil
	}
	if len(list) > 0 {
		newIds := make([]int64, 0)
		for _, item := range list {
			newIds = append(newIds, item.RoleId)
		}
		exist = append(exist, newIds...)
		return role.treeDel(newIds, exist)
	}
	return exist
}
